package com.yeziji.utils.expansion;

import cn.hutool.core.util.StrUtil;
import com.yeziji.common.CommonSymbol;
import com.yeziji.constant.VariousStrPool;

import javax.annotation.Nonnull;
import java.util.function.Consumer;

/**
 * 字符串工具类
 *
 * @author hwy
 * @since 2023/12/06 11:18
 **/
public class Str2 {
    /**
     * notBlankThen
     *
     * <p>不为空则进行其他操作</p>
     *
     * @param str      判断指定字符串
     * @param consumer 消费字符串行为
     */
    public static void notBlankThen(String str, @Nonnull Consumer<String> consumer) {
        if (StrUtil.isNotBlank(str)) {
            consumer.accept(str);
        }
    }

    /**
     * isBlankThen
     * <p>
     * 为空则进行其他操作
     * </p>
     *
     * @param str      判断指定字符串
     * @param consumer 消费字符串行为
     */
    public static void isBlankThen(String str, @Nonnull Consumer<String> consumer) {
        if (StrUtil.isBlank(str)) {
            consumer.accept(str);
        }
    }

    /**
     * isBlankElse
     * <p>如果为空则返回 else 值</p>
     *
     * @param str     判断字符串
     * @param elseStr else 值
     * @return {@link String} 实际字符串
     */
    public static String isBlankElse(String str, @Nonnull String elseStr) {
        if (StrUtil.isBlank(str)) {
            return elseStr;
        }
        return str;
    }

    /**
     * 如果为 null 返回空字符串
     *
     * @param str 字符串
     * @return {@link String} 原字符串或空字符串
     */
    public static String nullEmpty(String str) {
        return Opt2.nullElse(str, VariousStrPool.EMPTY);
    }

    /**
     * 字符串全替换为空
     *
     * @param src    原字符串
     * @param target 目标字符串
     * @return {@link String} 替換結果
     */
    public static String replaceAllToEmpty(String src, String target) {
        return replaceAllStr(src, target, VariousStrPool.EMPTY);
    }

    /**
     * 字符串全替换
     *
     * @param src         原字符串
     * @param target      目标字符串
     * @param replacement 替换的内容
     * @return {@link String} 替換結果
     */
    public static String replaceAllStr(String src, String target, String replacement) {
        if (src == null || target == null || replacement == null) {
            return src;
        }
        int idx = src.indexOf(target);
        if (idx == -1) {
            return src;
        }
        int pst = 0;
        char[] cs = src.toCharArray();
        char[] rs = new char[src.length() - target.length() + replacement.length()];
        for (int i = 0; i < cs.length; i++) {
            if (i == idx) {
                for (char c : replacement.toCharArray()) {
                    rs[pst] = c;
                    pst++;
                }
                continue;
            }
            if (i > idx && i < idx + target.length()) {
                continue;
            }
            rs[pst] = cs[i];
            pst++;
        }
        return replaceAllStr(new String(rs), target, replacement);
    }

    /**
     * 字符串包含否？
     * <p>
     * 支持通配符 *
     * </p>
     *
     * @param str1       字符串 1
     * @param str2       字符串 2
     * @param ignoreCase 是否忽略大小写
     * @return {@link Boolean} 字符串 1 是否包含字符串 2
     */
    public static boolean contain(String str1, String str2, boolean ignoreCase) {
        if (!ignoreCase) {
            return contain(str1, str2);
        }
        return contain(str1.toLowerCase(), str2.toLowerCase());
    }

    /**
     * 字符串包含否？
     * <p>
     * 支持通配符 *
     * </p>
     *
     * @param str1 字符串 1
     * @param str2 字符串 2
     * @return {@link Boolean} 字符串 1 是否包含字符串 2
     */
    public static boolean contain(String str1, String str2) {
        // 如果两个字符串都为空或空白，则返回 true, 反之任意一方为空，另一方不为空则返回 false
        if (StrUtil.isBlank(str1) && StrUtil.isBlank(str2)) {
            return true;
        } else if (StrUtil.isBlank(str1) || StrUtil.isBlank(str2)) {
            return false;
        }

        // 检查 str1 是否包含通配符 *, 如果通配符在开头，直接返回 true
        int allFlag = str1.indexOf(CommonSymbol.STAR_SIGN);
        if (allFlag == 0) {
            return true;
        }

        // 如果通配符在中间或末尾，检查 str2 是否以 str1 的前缀开始
        return allFlag > 0 ? str2.startsWith(str1.substring(0, allFlag)) : str2.equals(str1);
    }

    /**
     * 将字符串中的指定分隔符转换为驼峰式。
     *
     * @param input      原始字符串
     * @param delimiters 分隔符数组
     * @return 转换后的字符串
     */
    public static String toCamelCase(String input, char... delimiters) {
        if (input == null || input.isEmpty()) {
            return input;
        }

        boolean nextUpperCase = false;
        StringBuilder result = new StringBuilder();
        for (char c : input.toCharArray()) {
            if (isDelimiter(c, delimiters)) {
                nextUpperCase = true;
            } else {
                if (nextUpperCase) {
                    result.append(Character.toUpperCase(c));
                    nextUpperCase = false;
                } else {
                    result.append(c);
                }
            }
        }
        return result.toString();
    }

    /**
     * 检查字符是否在分隔符数组中。
     *
     * @param c          待检查的字符
     * @param delimiters 分隔符数组
     * @return 如果字符在分隔符数组中，返回 true；否则返回 false
     */
    private static boolean isDelimiter(char c, char[] delimiters) {
        for (char delimiter : delimiters) {
            if (c == delimiter) {
                return true;
            }
        }
        return false;
    }

    /**
     * 将数值转换为指定的字符串
     * <p>
     * 1 -> 0001 (number = 1, length = 4)
     * 2 -> 00002 (number = 1, length = 5)
     * </p>
     *
     * @param number 要转换的数值
     * @param length 0 的长度
     * @return {@link String}
     */
    public static String formatNumber(int number, int length) {
        return String.format("%0" + length + "d", number);
    }

    /**
     * 解决重复 json 序列化
     *
     * @param json json
     * @return {@link String}
     */
    public static String resolveOverrideJson(String json) {
        // json 多次序列化会生成重复的横杠
        json = StrUtil.replaceFirst(json, "\"", "");
        json = StrUtil.replaceLast(json, "\"", "");
        json = json.replace("\\\"", "\"").replace("\\\"", "\"");
        return json;
    }

    public static void main(String[] args) {
        System.out.println(toCamelCase("a-b_c", '-', '_'));
    }
}
